JavaScript 设计模式之其他设计模式

Author Avatar
Klein 8月 30, 2018

原型模式

概念

  • clone 自己,生成一个新对象。
  • Object.creat()

桥接模式

概念

  • 用于把抽象与实现化解耦
  • 使得二者可以独立变化

代码演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Color {
constructor(name) {
this.name = name
}
}

class Shape {
constructor(name, color) {
this.name = name
this.color = color
}
draw() {
console.log(`${this.color.name} ${this.name}`);
}
}

// 测试代码
let red = new Color('red')
let yellow = new Color('yellow')
let circle = new Shape('circle', red)
circle.draw()
let triangle = new Shape('triangle', yellow)
triangle.draw()

设计原则验证

  • 抽象和实现分离,解耦
  • 符合开放封闭原则

组合模式

概念

  • 生成属性结构,表示 “整体-部分” 关系
  • 让整体和部分都具有一致的操作方式
  • 整体和单个节点的数据结构也要吃一致

设计原则验证

  • 将整体和单个节点的操作抽象出来
  • 符合开放封闭原则

享元模式

概念

  • 共享内存(主要考虑内存,而非效率)
  • 相同的数据,共享使用

    设计原则验证

  • 将相同的部分抽象出来
  • 符合开放封闭原则

策略模式

  • 不同策略分开处理
  • 避免出现大量 if...else 或者 switch...case

    设计原则验证

  • 不同策略分开处理,而不是混合在一起
  • 符合开放封闭原则

模板方法模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Action {
handle() {
handle1()
handle2()
handle3()
}
handle1() {
console.log('1')
}
handle2() {
console.log('2')
}
handle3() {
console.log('3')
}
}

职责链模式

概念

  • 一步操作可能分为多个职责角色来完成
  • 把这些角色都分开,然后用一个链串起来
  • 将发起者和各个处理者进行隔离
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

// 请假审批,需要组长审批、经理审批、最后总监审批

// 封装角色
class Action {
constructor(name) {
this.name = name
this.nextAction = null
}
setNextAction(action) {
this.nextAction = action
}
handle() {
console.log(`${this.name} 审批`);
if (this.nextAction != null) {
this.nextAction.handle()
}
}
}

let a1 = new Action('组长')
let a2 = new Action('经理')
let a3 = new Action('总监')
a1.nextAction(a2)
a2.nextAction(a3)
a1.handle()

JavaScript 中的链式操作

  • jQuery
  • Promise

设计原则验证

  • 发起者和各个处理者进行隔离
  • 符合开
    放封闭原则

命令模式

概念

  • 执行命令时,发布者和执行者分开
  • 中间加入命令对象,作为中转站

代码演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class Receiver {
exec() {
console.log('执行');
}
}

class Command {
constructor(receiver) {
this.receiver = receiver
}
cmd() {
console.log('触发命令');
this.receiver.exec()
}
}

class Invoker {
constructor(command) {
this.command = command
}
invoke() {
console.log('开始');
this.command.cmd()
}
}

// 测试

// 士兵
let soldier = new Receiver()

// 旗手
let trumpter = new Command(soldier)

// 将军
let general = new Invoker(trumpter)
general.invoke()

设计原则验证

  • 命令对象与执行对象分开、解耦
  • 符合开放封闭原则

备忘录模式

概念

  • 随时记录一个对象的状态变化
  • 随时可以恢复之前的某个状态(撤销功能)

代码演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

// 状态备忘
class Memento {
constructor(content) {
this.content = content
}
getcontent() {
return this.content
}
}

// 备忘列表
class CareTaker() {
constructor() {
this.list = []
}
add(memento) {
this.list.push(memento)
}
get(index) {
return this.list[index]
}
}

// 编辑器
class Editor {
constructor() {
this.content = null
}
setContent(content) {
this.content = content
}
getContent(content) {
this.content = content
}
saveContentToMemento() {
return new Memento(this.content)
}
getContentFromMemento(memento) {
this.content = memento.getContent()
}
}


// 测试
let editor = new Editor()
let careTaker = new CareTaker()
editor.setContent('111')
editor.setContent('222')
careTaker.add(editor.saveContentToMemento())
editor.setContent('333')
careTaker.add(editor.saveContentToMemento())
editor.setContent('444')

console.log(editor.getContent());
editor.getContentFromMemento(careTaker.get(1))
console.log(editor.getContent());
editor.getContentFromMemento(careTaker.get(0))
console.log(editor.getContent());

中介者模式

概念

代码演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class Mediator {
constructor(a, b) {
this.a = a
this.b = b
}
setA() {
let number = this.b.number
this.a.setNumber(number * 100)
}
setB() {
let number = this.a.number
this.b.setNumber(number / 100)
}
}

class A {
constructor() {
this.numnber = 0
}
setNumber(num, m) {
this.number = num
if (m) {
m.setB()
}
}
}

class B {
constructor() {
this.numnber = 0
}
setNumber(num, m) {
this.number = num
if (m) {
m.setA()
}
}
}

设计原则验证

  • 将个关联对象通过中介者隔离
  • 符合开放封闭原则

访问者模式

  • 将数据操作和数据结构进行分离
  • 使用场景不多

解释器模式

  • 描述语言语法如何定义,如何解释和编译
  • 用于专业场景